package com.it.gmall.mq.listener;

import com.it.gmall.mq.config.DeadLetterMqConfig;
import com.it.gmall.mq.config.DelayedMsgConfig;
import com.it.gmall.mq.consts.MqConst;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

@Component
@Slf4j
public class ReceiverMsgListener {

    // @RabbitHandler
    /*普通消息*/
    @RabbitListener(queues = "queue111")
    public void msgListener(String msg, Message message, Channel channel){

        /*监听器-消费者
        * 手动应答消息
        *
        * basicAck();
        * long deliveryTag 消息标识, boolean multiple 是否批量
        * Boolean requeue 是否将这个消息重新放回队列 重新发送*/
        try {
            /*
             * 消息的组成：
             * 1.消息体--二进制格式
             * 2.消息属性--消息头和消息的其他属性*/
            System.out.println("接收到的消息是:"+msg);
            System.out.println("消息体中的消息是:"+new String(message.getBody()));

            log.info("接收到了消息");

            // 异常
            int i = 10/0;

            // 手动应答消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

        } catch (Exception e) {// 消息应答失败
            // e.printStackTrace();

            // 判断是否是重发消息
            Boolean redelivered = message.getMessageProperties().isRedelivered();

            if(redelivered){// 是重发消息 拒绝这个消息

                // 拒绝消息 为了不阻塞信道 影响后面的消息
                try {
                    log.error("消息重发的次数耗尽了");
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

            }else{ // 不是重发的消息 再给一次机会 重新发送一次 重新放回信道
                try {
                    log.info("尝试重发一次消息");
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }

        }
    }

    /*基于死信的延迟消息*/
    @RabbitListener(queues = DeadLetterMqConfig.queue_dead_2)
    public void deadLetterMsgListener(String msg, Message message, Channel channel){
        try {
            System.out.println("接收到的消息是:"+msg);
            System.out.println("接收到消息的时间是:"+new Date());

            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*基于插件的延迟消息*/
    @RabbitListener(queues = DelayedMsgConfig.queue_delay_1)
    public void delayedMsgListener(String msg, Message message, Channel channel){
        try {
            System.out.println("接收到的消息是:"+msg);
            System.out.println("接收到消息的时间是:"+new Date());

            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
